package fileExplorer;

import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.*;


/** 
 *  This class contains the search algorithm to search for a file everwhere within the computer.
 */
public class FileSearch{
/* {author=George Siegle}*/
	
	private String fileName;	
	private boolean cancelSearch = false;
	private JFrame statusFrame = new JFrame();
	private JLabel statusLabel = new JLabel("Currently searching:");
	private JLabel statusOfScanLabel = new JLabel("Scanning");
	private GridBagConstraints statusFrameConstraints = new GridBagConstraints();
	private JButton cancelButton = new JButton("Cancel");
	private JProgressBar fileSearchProgress = new JProgressBar();
	private DefaultListModel<String> filesThatMatchModelTmp;

	/** 
	 *  This method is the constructor for the FileSearch class. This constructor sets the local fileName variable to the value of the file name entered by the user. It then calls the appropriate class methods to search the computer for the file by that file name.
	 */
	public FileSearch(String fileName, DefaultListModel<String> filesThatMatch) {
	/* {author=George Siegle}*/
		filesThatMatchModelTmp = filesThatMatch;
		this.fileName = fileName;
		statusFrame.setTitle("Scan Status");
		statusFrame.setPreferredSize(new Dimension(500, 150));
		statusFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		statusFrame.getContentPane().setLayout(new GridBagLayout());
		statusFrameConstraints.fill = GridBagConstraints.HORIZONTAL;
		statusFrameConstraints.weightx = 0.5;
		statusFrame.getContentPane().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		statusFrameConstraints.gridx = 0;
		statusFrameConstraints.gridy = 0;
		statusFrame.getContentPane().add(statusLabel, statusFrameConstraints);
	  
		statusFrameConstraints.fill = GridBagConstraints.HORIZONTAL;
		statusFrameConstraints.weightx = 0.5;
		statusFrameConstraints.gridx = 0;
		statusFrameConstraints.gridy = 1;
		statusFrame.getContentPane().add(statusOfScanLabel, statusFrameConstraints);
	  
		statusFrameConstraints.fill = GridBagConstraints.HORIZONTAL;
		statusFrameConstraints.weightx = 0.5;
		statusFrameConstraints.gridx = 0;
		statusFrameConstraints.gridy = 2;
		statusFrame.getContentPane().add(cancelButton, statusFrameConstraints);
		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				cancelSearch = true;
			}
		});
	  
		fileSearchProgress.setIndeterminate(true);
		statusFrameConstraints.fill = GridBagConstraints.HORIZONTAL;
		statusFrameConstraints.weightx = 0.5;
		statusFrameConstraints.gridx = 0;
		statusFrameConstraints.gridy = 3;
		statusFrame.getContentPane().add(fileSearchProgress, statusFrameConstraints);
	  
		((JFrame)statusLabel.getTopLevelAncestor()).pack();
		((JFrame)statusOfScanLabel.getTopLevelAncestor()).pack();
		((JFrame)cancelButton.getTopLevelAncestor()).pack();
		((JFrame)fileSearchProgress.getTopLevelAncestor()).pack();
		statusFrame.pack();
		statusFrame.setVisible(true);
		searchForFile();
		statusFrame.setVisible(false);
		statusFrame.dispose();
		filesThatMatch = filesThatMatchModelTmp;
	}

	/** 
	 *  This method searches the computer for the file with the file name specified by the user.
	 */
	private void searchForFile() {
	/* {author=George Siegle}*/
		File[] rootFiles = File.listRoots();
		for (File file : rootFiles) {
			if (!cancelSearch) {
				statusOfScanLabel.setText(file.toString());
				if (file.isDirectory()) {
					digIntoRootFolders(file.getPath());
				}
				else {
					String[] splitPath = file.toString().split("[\\\\]");
					if (splitPath[splitPath.length - 1].equals(fileName)) {
						filesThatMatchModelTmp.addElement(file.toString());
					}
				}
			}
			else {
				break;
			}
		}
	}
  
	/**
	 * Method that searches for all folders and files in the currently selected folder.
	 */
	private void digIntoRootFolders(String parentDir) {
	/* {author=George Siegle}*/
		File[] filesInDir = new File(parentDir).listFiles();
		if (filesInDir != null) {
			for (File file : filesInDir) {
				if (!cancelSearch) {
					statusOfScanLabel.setText(file.toString());
					if (file.isDirectory()) {
						digIntoRootFolders(file.getAbsolutePath());
					}
					String[] splitPath = file.toString().split("[\\\\]");
					if (splitPath[splitPath.length - 1].equals(fileName)) {
						filesThatMatchModelTmp.addElement(file.toString());
					}
				}
				else {
					break;
				}
			}
		}
		else {
			statusOfScanLabel.setText(parentDir);
			String[] splitPath = parentDir.split("[\\\\]");
			if (splitPath[splitPath.length - 1].equals(fileName)) {
				filesThatMatchModelTmp.addElement(parentDir.toString());
			}
		}
	}
}